﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace MaterialEditor
{
    /// <summary>
    /// Defines a type of texture effect
    /// </summary>
    public enum TextureEffectType
    {
        Pan,
        Tesselate,
        Rotate,
    }

    public interface IEffect
    {
        Vector2 Value { get; }

        Matrix Transform { get; }

        Effect effect { get; }

        IEffect Clone();

        Texture2D[] textures { get; }
    }

    /// <summary>
    /// Stores the behavor(s) for a texture
    /// </summary>
    public class TextureEffects
    {
        public TextureEffectType type;

        List<IEffect> children;

        private static Vector2[] texCoords = new Vector2[]
        {
            new Vector2(0.0f, 0.0f),
            new Vector2(0.0f, 1.0f),
            new Vector2(1.0f, 0.0f),
            new Vector2(1.0f, 1.0f),
        };

        public TextureEffects(params IEffect[] effects)
        {
            children = new List<IEffect>(effects);
        }

        /// <summary>
        /// The ammount of children in the container
        /// </summary>
        public int Count
        {
            get { return children.Count; }
        }

        public IEffect this[int i]
        {
            get { return children[i]; }

            set { children[i] = value; }
        }

        public Vector2[] TexCoords
        {
            get
            {
                Vector2[] outval = new Vector2[texCoords.Length];

                Matrix transform = Matrix.Identity;
                for (int i = 0; i < children.Count; i++)
                    transform *= children[i].Transform;

                Vector2.Transform(texCoords, ref transform, outval);

                return outval;
            }
        }

        public static TextureEffects operator +(TextureEffects a, TextureEffects b)
        {
            // allocate all the children we're going to put into the new TextureEffects
            List<IEffect> children = new List<IEffect>();
            // copy all of a and bs children to the new children collection
            for (int i = 0; i < a.children.Count; i++)
                children.Add(a.children[i]);

            for (int i = 0; i < b.children.Count; i++)
                children.Add(b.children[i]);

            // return combined texture effects
            return new TextureEffects(children.ToArray());
        }

        public static TextureEffects operator +(TextureEffects a, IEffect b)
        {
            a.children.Add(b);

            return a;
        }
    }
}